package isv

import (
    //"os"
	"fmt"
	"time"
	"strconv"
	"encoding/json"
	"dhfshop/utils/uuid"
	"encoding/base64"
    "dhfshop/models/isv"
	"dhfshop/controllers/base"
	"github.com/astaxie/beego/validation"
	"github.com/astaxie/beego"
	"dhfshop/domain/nsqproc"
	"wxsdk/mp/material"
	"wxsdk/miniapp/core"
)

type TempMaterialController struct {
	base.BaseController
}

// 查询微信平台临时素材
func (this *TempMaterialController) Get() {
    v := struct {
	    AuthorizerAppid string  `form:"authorizer_appid" valid:"Required"`
		MediaId         string  `form:"media_id" valid:"Required"`
	    IsBase64        bool    `form:"base64"`
	}{IsBase64:false} 
	this.ParseForm(&v)
	valid := validation.Validation{}
	passed, _ := valid.Valid(&v)
	if !passed {
		this.ServeError(valid.Errors[0].Key+" "+valid.Errors[0].Message)
		return 
	}
	custAccount, err := isv.GetCustAccountByAppId(v.AuthorizerAppid)
	if err != nil {
	    this.ServeError(err.Error())
		return
	}
	_, data, err := material.GetTemporaryMaterial(custAccount.AccessToken, v.MediaId)
	if err != nil {
	    this.ServeError(err.Error())
		return
	}
	//helper.WritetoFile("tmp.jpg", data)
	//
	//this.Ctx.Output.Header("Content-Type", headPara["Type"])
	//this.Ctx.Output.Header("Content-Length", headPara["Length"])
	//this.Ctx.Output.Header("Content-Disposition", headPara["Disposition"])
	//this.Ctx.ResponseWriter.Write(data)
	if v.IsBase64 {
	    // 为了浏览器兼容，base64编码一下
		encodeString := base64.StdEncoding.EncodeToString(data)
		this.Ctx.ResponseWriter.Write([]byte(encodeString))
	}else{
	    this.Ctx.ResponseWriter.Write(data) 
	}
}

// 临时素材上传
func (this *TempMaterialController) Upload() {
    authorizerAppid := this.GetString("authorizer_appid")
	if len(authorizerAppid) < 3 {
	    this.ServeError("authorizer_appid is invalid")
		return
	}
	custAccount, err := isv.GetCustAccountByAppId(authorizerAppid)
	if err != nil {
	    this.ServeError(err.Error())
		return
	}
	file, _, err := this.GetFile("wxfile")
	if err != nil {
		this.ServeError(err.Error())
		return
	}
	media, err := material.MediaUploadByIoReader(custAccount.AccessToken, "image", file)
	/*
	filePath := "static/uploads/tempmaterial.jpg"
	err = this.SaveToFile("wxfile", filePath)
	if err != nil {
		this.ServeError(err.Error())
		return
	}
	media, err := material.MediaUploadByName(custAccount.AccessToken, "image", filePath)
	os.Remove(filePath)
	if err != nil {
	    this.ServeError(err.Error())
		return
	}
	*/
	materialRecord := new(isv.MaterialRecord)
	materialRecord.PartnerId = 0     //???
	materialRecord.AppId = authorizerAppid
	materialRecord.PropertyId = 2
	materialRecord.MediaType = "image"
	materialRecord.MediaId = media.MediaId
	materialRecord.CreatedAt = media.CreatedAt - 8*3600
	materialRecord.ExpiredAt = media.CreatedAt - 8*3600 + 3*24*3600
	isv.AddMaterialRecord(materialRecord)
	this.Data["json"] = media
	this.ServeJSON()
}

func (this *TempMaterialController) UploadRecordList() {
	query,_,fields,order_by,offset,limit,err := this.GetQueryPara()
	if err != nil {
	   this.ServeError(err.Error())
	   return
	}
	
	l, cnt, err := isv.GetAllMaterialRecords(query,fields,order_by,offset,limit)
	if err != nil {
	    this.ServeError(err.Error())
		return
	}
	r := struct {
		TotalCount       int64                 `json:"total_count"`
		MaterialRecords  []*isv.MaterialRecord `json:"materialRecords"`
	}{TotalCount: cnt, MaterialRecords: l}
	this.Data["json"] = r
	this.ServeJSON()
}
/******************************************************/
func (this *TempMaterialController) SimuTaskPost() {
	var v isv.MateSimuTask
	this.ParseForm(&v)
	valid := validation.Validation{}
	valid.Required(v.AppId, "app_id")
	valid.Required(v.ApplyType, "apply_type")
	passed, _ := valid.Valid(&v)
	if !passed {
		this.ServeError(valid.Errors[0].Key+" "+valid.Errors[0].Message)
		return
	}
	custAccount, err := isv.GetCustAccountByAppId(v.AppId)
	if err != nil {
		this.ServeError(err.Error())
		return
	}
	imgData, err := core.GetCommonFileByHttp(v.LocalUrl)
	if err != nil {
	    this.ServeError(err.Error())
		return
	}
	media, err := material.MediaUploadByData(custAccount.AccessToken, "image", imgData)
	if err != nil {
		this.ServeError(err.Error())
		return
	}
	v.MediaType = media.Type
	v.MediaId = media.MediaId
	v.PartnerId = int64(this.Ctx.Input.GetData("curCompanyId").(int))
	v.MateSimuTaskId, _= uuid.GetSnowFlakeId(uuid.Worker)
	v.ExpiredAt = time.Now().UTC().Add(time.Hour * 24 * 3)
	mateSimuTaskIdStr := fmt.Sprintf("%d", v.MateSimuTaskId)
	//
	types := "materialtimer"
	ttlSeconds := 70*3600
	body := struct {
		Types          string `json:"types"`
		MateSimuTaskId int64  `json:"mate_simu_task_id"`
	}{Types:types, MateSimuTaskId: v.MateSimuTaskId}
	if callBackData, err := json.Marshal(&body); err == nil {
		if err = nsqproc.RpcAddTimerTask(types, string(callBackData), ttlSeconds); err != nil {
		    beego.Debug("RpcAddTimerTask:", err.Error())
		}
	}
	if _, err = isv.AddMateSimuTask(&v); err != nil {
	    this.ServeError(err.Error())
		return
	}
	rsp := struct {
		MateSimuTaskId string     `json:"mate_simu_task_id"`
	    Created        time.Time  `json:"created"`
	}{MateSimuTaskId:mateSimuTaskIdStr,Created:time.Now().UTC()}
	this.Data["json"] = rsp
	this.ServeJSON()
}

func (this *TempMaterialController) SimuTaskList() {
	query,_,fields,order_by,offset,limit,err := this.GetQueryPara()
	if err != nil {
	   this.ServeError(err.Error())
	   return
	}
	list, num, err := isv.GetAllMateSimuTasks(query,fields,order_by,offset,limit)
	if err != nil {
	    this.ServeError(err.Error())
	    return
	   
	} 
	r := struct {
	    TotalCount    int64               `json:"total_count"`
	    MateSimuTasks []*isv.MateSimuTask `json:"mate_simu_tasks"`
	}{TotalCount: num, MateSimuTasks: list}
	this.Data["json"] = r
	this.ServeJSON()
}

func (this *TempMaterialController) SimuTaskDelete() {
    companyId := int64(this.Ctx.Input.GetData("curCompanyId").(int))
    //curUserId := this.Ctx.Input.GetData("curUserId").(int)
	v := struct {
		CompanyId         int64   `form:"-"  valid:"Required;Min(1)"`
	    MateSimuTaskIdStr string  `form:"mate_simu_task_id" valid:"Required"`
	}{CompanyId: companyId} 
	this.ParseForm(&v)
	valid := validation.Validation{}
	passed, _ := valid.Valid(&v)
	if !passed {
		this.ServeError(valid.Errors[0].Key+" "+valid.Errors[0].Message)
		return
	}
	mateSimuTaskId, err := strconv.ParseInt(v.MateSimuTaskIdStr, 10, 64)
	if err != nil {
		this.ServeError(err.Error())
		return
	}
	if err := isv.DeleteMateSimuTaskById(mateSimuTaskId); err != nil {
		this.ServeError(err.Error())
		return
	}
	rsp := struct {
		MateSimuTaskIdStr string      `json:"mate_simu_task_id"`
		Modified          time.Time   `json:"modified"`
	}{MateSimuTaskIdStr:v.MateSimuTaskIdStr, Modified:time.Now().UTC()}
	this.Data["json"] = rsp
	this.ServeJSON()
}
